package com.woniuxy.yogaapp.handler;

import java.util.Date;
import javax.annotation.Resource;
import com.woniuxy.yogaapp.dto.UserDto;
import com.woniuxy.yogaapp.dto.UserImageDto;
import com.woniuxy.yogaapp.service.UserService;
import com.woniuxy.yogaapp.util.ShiroSession;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.woniuxy.yogaapp.pojo.User;

import com.woniuxy.yogaapp.util.RegexUtil;
import com.woniuxy.yogaapp.util.SMSUtil;
import lombok.Data;

@Data
@Controller
@RequestMapping("/user")
@Scope("prototype")
public class UserHandler {
	@Resource
	private UserService userService;
	private static String codeSum;
	private static long firstTime;

	/**
	 * 获取验证码
	 * 
	 * @return
	 */
	@RequestMapping("/getCode")
	@ResponseBody
	public String getCode(User user) {
		String result = "验证码获取成功！";
		// 获取前端传来的手机号
		String phoneNumber = user.getAccount();
		if (phoneNumber == null || phoneNumber.length() == 0) {
			return "手机号不能为空！";
		}
		// 手机号合法性判断
		if (!RegexUtil.isMobile(phoneNumber)) {
			return "手机号格式有误，你输入11位正确手机号！";
		}
		String sum = Integer.toString((int) ((Math.random() * 9 + 1) * 100000));
		// 为私有属性赋值
		codeSum = sum;
		firstTime = new Date().getTime();
		String[] params = { sum, "1" };
		SMSUtil.getCode(phoneNumber, params);
		return result;
	}

	/**
	 * 用户注册
	 * 
	 * @param userDto
	 *            account账号 pass密码 code验证码
	 * @return
	 */
	@RequestMapping("/register")
	@ResponseBody
	public String register(UserDto userDto) {
		// System.out.println(codeSum);
		String account = userDto.getAccount();
		String pass = userDto.getPass();
		String code = userDto.getCode();
		if (account == null || account.length() == 0 || pass == null || pass.length() == 0) {
			return "账号或密码不能为空！";
		}
		// 1.验证码是否为空
		if (code == null || code.length() == 0) {
			return "验证码不能为空！";
		}
		// 判断用户是否获取了验证码
		if (codeSum == null || codeSum.length() == 0) {
			return "你还未获取验证码,请获取后输入正确验证码！";
		}
		// 2.验证码是否过了60秒
		// param1：获取验证码的时间戳 param2：点击注册时的时间戳 param3:失效时间设置
		boolean flag = SMSUtil.loseTime(firstTime, new Date().getTime(), 60);
		if (flag) {
			return "验证码已经失效，请重新获取！";
		}
		// 3.验证码是否正确
		if (!codeSum.equals(code)) {
			return "验证码有误，请输入正确验证码！";
		}
		// 4.数据库查询该账号是否已经存在
		User user_account = new User();
		user_account.setAccount(account);
		User uu = userService.login(user_account);
		if (uu != null) {
			return "该账户已经注册过，不能重复注册！";
		}
		// 使用md5加密 加密次数1024
		String passNew = new SimpleHash("MD5", pass, null, 1024).toString();
		User user = new User(0, account, passNew);
		// 调用service保存数据方法
		String result = userService.addUser(user);

		return result;
	}

	/**
	 * 登录
	 * 
	 * @param user
	 * @return
	 */
	@RequestMapping("/login")
	@ResponseBody
	public String login(User user) {

		// 1.获取subject对象
		Subject currentUser = SecurityUtils.getSubject();
		// 2.判断当前用户是否已经认证过了
		if (!currentUser.isAuthenticated()) {
			// 3.进行认证
			UsernamePasswordToken token = new UsernamePasswordToken(user.getAccount(), user.getPass());

			try {
				currentUser.login(token);// 进行认证
				/*
				 * 1.执行currentUser.login(token)方法时会调用securityManager中的
				 * login()方法，同时将token传递过去
				 * 2.securityManager会根据shiro配置文件中的配置信息自动的调用
				 * 自定义realm的doGetAuthenticationInfo()方法，获取账号信息
				 * 3.如果该方法返回值是null，直接抛出UnknownAccountException异常
				 * 否则该方法将查询到的账号密码返回给securityManager
				 * 4.securityManager根据返回的结果比较密码是否一致
				 * 如果不一致抛出IncorrectCredentialsException异常 如果一致，代表认证成功
				 */
				System.out.println("认证成功!(账号密码都对)");
				// 跳转到主界面
				return "认证成功!(账号密码都对)";
			} catch (UnknownAccountException e) {
				System.out.println("用户不存在");
				return "用户不存在";
				// 让其继续登录
			} catch (IncorrectCredentialsException e) {
				System.out.println("密码不对");
				return "密码不对";
			} catch (LockedAccountException e) {
				System.out.println("账户被锁定");
				return "账户被锁定";
			} catch (AuthenticationException e) {
				System.out.println("其他异常");
				return "其他异常";
			}

		}
		return "你已经登录过了，请注销后再登录！";

	}

	/**
	 * 密码 找回 设置新密码保存
	 * 
	 * @param userDto
	 * @return
	 */
	@RequestMapping("/findPass")
	@ResponseBody
	public String findPass(UserDto userDto) {
		String result = "密码已找回！";
		String account = userDto.getAccount();
		String pass = userDto.getPass();
		String code = userDto.getCode();
		if (account == null || account.length() == 0 || pass == null || pass.length() == 0) {
			return "账号或密码不能为空！";
		}
		// 1.验证码是否为空
		if (code == null || code.length() == 0) {
			return "验证码不能为空！";
		}
		// 判断用户是否获取了验证码
		if (codeSum == null || codeSum.length() == 0) {
			return "你还未获取验证码,请获取后输入正确验证码！";
		}
		// 2.验证码是否过了60秒
		// param1：获取验证码的时间戳 param2：点击注册时的时间戳 param3:失效时间设置
		boolean flag = SMSUtil.loseTime(firstTime, new Date().getTime(), 60);
		if (flag) {
			return "验证码已经失效，请重新获取！";
		}
		// 3.验证码是否正确
		if (!codeSum.equals(code)) {
			return "验证码有误，请输入正确验证码！";
		}
		// 4.数据库查询该账号是否已经存在
		User user_account = new User();
		user_account.setAccount(account);
		User uu = userService.login(user_account);
		if (uu == null) {
			return "该账号不存在，不能进行密码找回！";
		}
		// 5.设置新密码
		// 使用md5加密 加密次数1024
		String passNew = new SimpleHash("MD5", pass, null, 1024).toString();
		User user = new User(0, account, passNew);
		int row = userService.updateNewPass(user);
		if (row == 1) {
			result = "密码已找回，请使用新密码登录！";
		}
		return result;

	}

	/**
	 * 获取当前用户的信息
	 * @return
	 */
	@RequestMapping("/findUidImage")
	@ResponseBody
	public UserImageDto findUidImage() {

		//获取uid
		Subject currentUser = SecurityUtils.getSubject();
		Session session = currentUser.getSession();
		if (session == null) {
			return null;
		}
		//获取uid
		Object uidObject = session.getAttribute("uid");
		if (uidObject == null) {
			return null;
		}
		Integer uid = (Integer) uidObject;
		//获取名字和头像
		return  userService.findUidImage(uid);
	}

	/**
	 * 获取用户的角色
	 * @return
	 */
	@RequestMapping("/getRoles")
	@ResponseBody
	public Integer getRoles() {
		// 1.获取subject对象
				Subject currentUser = SecurityUtils.getSubject();
				Session session = currentUser.getSession();
				Integer uid = (Integer) session.getAttribute("uid");
				System.out.println(uid);
		if (uid == null || uid == 0) {
			return -1;
		}
		Integer roles = userService.findRoleByUid(uid);

		return roles;
	}

}
